#include "TTT.hpp"

namespace MA {

#define TEX_BASE_OFFSET 16
#define TEX_LINE_WIDTH 6
#define TEX_MOVE_OFFSET 146
#define TEX_SIZE	146

TTT::TTT()
    : m_curPlayer('x') {
    for (uint8_t i = 0; i < 3; ++i) {
        for (uint8_t j = 0; j < 3; ++j) {
            m_map[i][j] = ' ';
        }
    }
}


void TTT::loadResource(SDL_Renderer* renderer) {
    m_bgTex.loadImage(renderer, "../Game_Tic-Tac-Toe/Texture/tic_tac_toe_#.png");
    m_xTex.loadImage(renderer, "../Game_Tic-Tac-Toe/Texture/tic_tac_toe_x.png");
    m_oTex.loadImage(renderer, "../Game_Tic-Tac-Toe/Texture/tic_tac_toe_o.png");
}

char TTT::update() {
    uint8_t fillCount = 0;

    // Match vertical
    for (uint8_t i = 0; i < 3; ++i) {
        if (m_map[i][0] == m_map[i][1] && m_map[i][1] == m_map[i][2]) {
            return m_map[i][0];
        }

        if (m_map[i][0] != ' ') {
            ++fillCount;
        }
        if (m_map[i][1] != ' ') {
            ++fillCount;
        }
        if (m_map[i][2] != ' ') {
            ++fillCount;
        }
    }
    // Match horizental
    for (uint8_t i = 0; i < 3; ++i) {
        if (m_map[0][i] == m_map[1][i] && m_map[1][i] == m_map[2][i]) {
            return m_map[0][i];
        }
    }

    if (m_map[0][0] == m_map[1][1] && m_map[1][1] == m_map[2][2]) {
        return m_map[1][1];
    }

    if (m_map[2][0] == m_map[1][1] && m_map[1][1] == m_map[0][2]) {
        return m_map[1][1];
    }

    if (fillCount == 9) return '=';

    return ' ';
}

void TTT::draw(SDL_Renderer* renderer) {
    SDL_Rect area;
    area.w = TEX_SIZE;
    area.h = TEX_SIZE;

    m_bgTex.draw(renderer, nullptr, nullptr);

    for (uint8_t i = 0; i < 3; ++i) {
        for (uint8_t j = 0; j < 3; ++j) {
            switch (m_map[i][j]) {
            case ' ':
                break;
            case 'x':
                area.x = TEX_BASE_OFFSET + (TEX_MOVE_OFFSET + TEX_LINE_WIDTH) * i;
                area.y = TEX_BASE_OFFSET + (TEX_MOVE_OFFSET + TEX_LINE_WIDTH) * j;

                m_xTex.draw(renderer, nullptr, &area);
                break;
            case 'o':
                area.x = TEX_BASE_OFFSET + (TEX_MOVE_OFFSET + TEX_LINE_WIDTH) * i;
                area.y = TEX_BASE_OFFSET + (TEX_MOVE_OFFSET + TEX_LINE_WIDTH) * j;

                m_oTex.draw(renderer, nullptr, &area);
                break;
            default:
                break;
            }
        }
    }
}

char TTT::switchPlayer() {
    if (m_curPlayer == 'x')	{
       return m_curPlayer = 'o';
    }

    return m_curPlayer = 'x';
}

void TTT::setMap(uint8_t x, uint8_t y) {
    if (x > 2) x = 2;
    if (y > 2) x = 2;

    if (m_map[x][y] == ' ') {
        m_map[x][y] = m_curPlayer;

        switchPlayer();
    }
}

char TTT::getMap(uint8_t x, uint8_t y) {
    if (x > 2) x = 2;
    if (y > 2) x = 2;

    return m_map[x][y];
}

}
